package com.mbinno.android.comm.device;


import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;


import com.mbinno.android.comm.utils.EncryptedSharedPreferences;
import com.mbinno.android.comm.utils.SimHash;
import com.mbinno.android.comm.utils.SystemPropertiesUtil;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class AppEnvManager {

    private static final Map<String, Integer> propKeys = new HashMap<String, Integer>() {
        {
            put("ro.build.ab_update", 1);
            put("ro.build.characteristics", 1);
            put("ro.build.date", 1);
            put("ro.build.date.utc", 1);
            put("ro.build.description", 1);
            put("ro.build.display.id", 1);
            put("ro.build.fingerprint", 1);
            put("ro.build.flavor", 1);
            put("ro.build.host", 1);
            put("ro.build.id", 1);
            put("ro.build.product", 1);
            put("ro.build.tags", 1);
            put("ro.build.type", 1);
            put("ro.build.user", 1);
            put("ro.build.version.all_codenames", 1);
            put("ro.build.version.codename", 1);
            put("ro.build.version.min_supported_target_sdk", 1);
            put("ro.build.version.sdk", 1);
            put("ro.build.version.security_patch", 1);
//            product
            put("ro.product.board", 1);
            put("ro.product.product.brand", 1);
            put("ro.product.brand", 1);
            put("ro.product.build.date", 1);
            put("ro.product.build.date.utc", 1);
            put("ro.product.build.fingerprint", 1);
            put("ro.product.build.id", 1);
            put("ro.product.build.tags", 1);
            put("ro.product.build.type", 1);
            put("ro.product.cpu.abi", 1);
            put("ro.product.cpu.abilist", 1);
            put("ro.product.cpu.abilist32", 1);
            put("ro.product.cpu.abilist64", 1);
            put("ro.product.cpu.pagesize.max", 1);
            put("ro.product.device", 1);
            put("ro.product.locale", 1);
            put("ro.product.manufacturer", 1);
            put("ro.product.model", 1);
            put("ro.product.name", 1);

        }
    };
    private static final String APP_INFO_DEVICE = "APP_INFO_DEVICE";
    private EncryptedSharedPreferences sp;

    private final Context mContext;

    private String mFingerPrintId;

    private String mSimHash;


    public AppEnvManager(Context cx) {
        this.mContext = cx;
        init(cx);
    }

    private void init(Context context) {
        sp = new EncryptedSharedPreferences(context);
    }

    private void initFingerPrintId() {
        try {
            mFingerPrintId = sp.getString(APP_INFO_DEVICE);
            if (TextUtils.isEmpty(mFingerPrintId)) {
                mFingerPrintId = getOriginalDeviceId();
                sp.setValue(APP_INFO_DEVICE, getOriginalDeviceId());
            }
        } catch (Exception e) {
            mFingerPrintId = FingerPintConfig.EX_PARSE_ID;
            e.printStackTrace();
        }

    }


    public synchronized String getFingerPrintId() {
        if (mFingerPrintId == null) initFingerPrintId();
        String simHash = getSimHash();

        //todo 判断运行环境，返回固定id
        String id = mFingerPrintId;
        String deviceId = getOriginalDeviceId();

        if (!deviceId.equals(id)) {
            //设备ID与解析出来的不一致?  是版本升级了还是设备被修改了属性？

        }

        return id + simHash;
    }

    private synchronized String getSimHash() {
        if (TextUtils.isEmpty(mSimHash)) {
//            Map<String, Integer> words = new HashMap<>();
//            Iterator<Map.Entry<String, Integer>> iterator = propKeys.entrySet().iterator();
//            while (iterator.hasNext()) {
//                Map.Entry<String, Integer> entry = iterator.next();
//                String key = SystemPropertiesUtil.getPropByShell(entry.getKey());
//                words.put(key, entry.getValue());
//            }
//            long hash = SimHash.calculateSimHash(words);
            Map<String, Integer> propertyMap = SystemPropertiesUtil.getAllPropertyMap();
            long hash = SimHash.calculateSimHash(propertyMap);
            mSimHash = Long.toHexString(hash).toUpperCase();
        }
        return mSimHash;
    }


    @SuppressLint("HardwareIds")
    public String getAndroidId() {
        String androidId = Settings.Secure.getString(mContext.getContentResolver(),
                Settings.Secure.ANDROID_ID);
        return androidId;
    }


//    public String getDeviceId() {
//        String imei = UNKNOWN;
//        TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
//
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//            return imei;
//        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//            imei = telephonyManager.getImei(0);
//        } else {
//            if (ActivityCompat.checkSelfPermission(mContext,
//                    Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
//                imei = telephonyManager.getDeviceId();
//            }
//        }
//        return imei;
//    }
//
//    public String getSerialNo() {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
//            return Build.getSerial();
//        }
//        return Build.SERIAL;
//    }
//
//
//    public String getMacAddress() {
//        return MacHelper.getMacAddress(mContext);
//    }
//
//    public String getFingerPrinter() {
//        return Build.FINGERPRINT;
//    }


    //    -------------------------------------original deviceid--------------

    public String getOriginalDeviceId() {
        String DeviceId = "";
        if (TextUtils.isEmpty(DeviceId)) {
            try {
                String serial;
                try {
                    serial = Build.SERIAL;
                } catch (Exception e) {
                    serial = "";
                }
                String m_szLongID = getAndroidId() + getPesudoUniqueID() + serial;
                // compute md5
                MessageDigest m = null;
                try {
                    m = MessageDigest.getInstance("MD5");
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                }
                m.update(m_szLongID.getBytes(), 0, m_szLongID.length());
                // get md5 bytes
                byte p_md5Data[] = m.digest();
                // create a hex string
                StringBuilder m_szUniqueID = new StringBuilder();
                for (byte aP_md5Data : p_md5Data) {
                    int b = (0xFF & aP_md5Data);
                    // if it is a single digit, make sure it have 0 in front (proper padding)
                    if (b <= 0xF) {
                        m_szUniqueID.append("0");
                    }
                    // add number to string
                    m_szUniqueID.append(Integer.toHexString(b));
                }   // hex string to uppercase
                DeviceId = m_szUniqueID.toString().toUpperCase();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return DeviceId;
    }

    private String getPesudoUniqueID() {
        String m_szDevIDShort = "35" + //we make this look like a valid IMEI
                Build.BOARD.length() % 10 +  //：The name of the underlying board, like "goldfish".
                Build.BRAND.length() % 10 +  //：The consumer-visible brand with which the product/hardware will be associated, if any
                Build.CPU_ABI.length() % 10 +  // cpu：The name of the instruction set (CPU type + ABI convention) of native code.
                Build.DEVICE.length() % 10 +  //：The name of the industrial design.
                Build.DISPLAY.length() % 10 +  //：A build ID string meant for displaying to the user
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +  //：The manufacturer of the product/hardware.
                Build.MODEL.length() % 10 +   //：The end-user-visible name for the end product.
                Build.PRODUCT.length() % 10;  //：The name of the overall product.
        return m_szDevIDShort;
    }

    //    -------------------------------------original deviceid end--------------


    public interface FingerPintConfig {

        /**
         * 解析错误，文件被导入
         */
        String EX_PARSE_ID = "";

        /**
         * 运行环境检测有部分数据修改
         */
        String EX_ENV_ID = "";
    }


    private class Properties {

    }
}
